const { exec } = require("child_process");
const os = require("os");
const routes = require("../routes.json");
const net = require("net");

/**
 * 获取一个未被占用的端口号
 * @param {number} [startPort=1024] - 起始端口号（默认从1024开始，避免使用系统保留端口）
 * @param {number} [endPort=65535] - 结束端口号（默认到65535）
 * @param {string} [host='127.0.0.1'] - 主机地址（默认本地）
 * @returns {Promise<number>} - 返回一个Promise，resolve时返回可用的端口号
 */
function getAvailablePort(
  startPort = 1024,
  endPort = 65535,
  host = "127.0.0.1"
) {
  return new Promise((resolve, reject) => {
    function checkPort(port) {
      if (port > endPort) {
        reject(new Error("No available port found in the given range"));
        return;
      }

      const server = net.createServer();
      server.once("error", (err) => {
        if (err.code === "EADDRINUSE") {
          // 端口被占用，检查下一个
          checkPort(port + 1);
        } else {
          reject(err);
        }
      });

      server.once("listening", () => {
        server.close(() => {
          resolve(port);
        });
      });

      server.listen(port, host);
    }

    // 验证端口范围
    if (startPort < 1 || startPort > 65535 || endPort < 1 || endPort > 65535) {
      reject(new Error("Port range must be between 1 and 65535"));
      return;
    }

    if (startPort > endPort) {
      reject(new Error("Start port must be less than or equal to end port"));
      return;
    }

    checkPort(startPort);
  });
}

// 获取本地 IP 地址
function getLocalIP() {
  const interfaces = os.networkInterfaces();
  for (const interfaceName in interfaces) {
    const iface = interfaces[interfaceName];
    for (const alias of iface) {
      if (alias.family === "IPv4" && !alias.internal) {
        return alias.address;
      }
    }
  }
  return "127.0.0.1"; // 如果没有找到外部 IP 地址，返回本地回环地址
}

// 启动 json-server
function startServer(port) {
  console.log("------------------------------\n");
  console.log(`Starting mock server on port ${port}\n`);
  const command = `json-server --watch ./src/mockData.js --port ${port} --routes ./src/routes.json --middlewares ./src/middlewares.js`;
  const baseUrl = `http://${getLocalIP()}:${port}`;
  console.log("Mock Server Api Urls:");
  for (let key in routes) {
    console.log(`${baseUrl}${routes[key]}`);
  }
  exec(command, (error, stdout, stderr) => {
    if (error) {
      console.error(`Error starting server: ${error.message}`);
      console.error(`Error details: ${stderr}`);
      return;
    }
    if (stderr) {
      console.error(`Server stderr: ${stderr}`);
      return;
    }
    console.log(`Server stdout: ${stdout}`);
  });
}

getAvailablePort(8000)
  .then((port) => {
    startServer(port);
  })
  .catch((err) => {
    console.error("获取端口失败:", err.message);
  });
